package ua.edu.nuos.jeetraining2012.cms.model;

import org.slf4j.Logger;
import ua.edu.nuos.jeetraining2012.cms.entity.StudentsToHomeWorkEntity;
import ua.edu.nuos.jeetraining2012.cms.entity.StudentsToHomeWorkId;
import ua.edu.nuos.jeetraining2012.cms.model.exception.DAOException;

import javax.ejb.Local;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

/**
 * DAO layer for students to homework relation.
 *
 * @author Victor N. Ganichev victor.ganichev@gmail.com
 * @version 1.0 Date: 27.06.13 Time: 12:59
 * @since 1.0
 */
@Local
@Stateless
public class StudentsToHomeWorkDAO {

    /** Define EntityManager */
    @PersistenceContext
    private EntityManager em;

    /** Define logger */
    final private Logger logger = org.slf4j.LoggerFactory.getLogger(StudentsToHomeWorkDAO.class);

    // Constructors.
    /** Default constructor. */
    public StudentsToHomeWorkDAO() {
        logger.debug("StudentsToHomeWorkDAO invocation.");
    }

    /**
     * Constructor with predefined EntityManager. Use this one for testing.
     *
     * @param em            Instance of EntityManager.
     */
    public StudentsToHomeWorkDAO(EntityManager em) {
        logger.debug("StudentsToHomeWorkDAO invocation with predefined EntityManager {}", em);
        setEm(em);
    }

    // Getters & Setters
    private EntityManager getEm() {
        return em;
    }

    protected void setEm(EntityManager em) {
        this.em = em;
    }

    // Custom methods.

    /**
     * Find out Students progress withing homework.
     * <p/>
     * To define user ID and homework ID, use complex key {@link StudentsToHomeWorkId}.<br/>
     * In case of success, {@link StudentsToHomeWorkEntity} will be returned or <code>null</code> if nothing
     * were found.
     * <p/>
     * If id is null, IllegalArgumentException will be thrown.
     * If id.getStudentId() returns null or is empty, IllegalArgumentException will be thrown.
     * If id.getHomeWorkId() returns number less than 1, IllegalArgumentException will be thrown.
     *
     * @param id                                Complex key.
     * @return                                  Instance of StudentsToHomeWorkEntity or <code>null</code>.
     * @throws IllegalArgumentException         If id is null.
     *                                          If id.getStudentId() is null or empty.
     *                                          If id.getHomeworkId() is less than 1.
     * @throws DAOException                     If any parent exception appeared, during progress search.
     */
    public StudentsToHomeWorkEntity findStudentProgressById(StudentsToHomeWorkId id) throws IllegalArgumentException, DAOException {
        logger.debug("findStudentProgressById() - started.");

        if (id == null) {
            logger.error("Id can't be null");
            logger.debug("findStudentProgressById() - finished with IllegalArgumentException.");
            throw new IllegalArgumentException("Id can't be null");
        }

        if (id.getStudentId() == null || id.getStudentId().isEmpty()) {
            logger.error("User ID can't be {}", id.getStudentId());
            logger.debug("findStudentProgressById() - finished with IllegalArgumentException.");
            throw new IllegalArgumentException("User ID can't be null or empty");
        }

        if (id.getHomeworkId() < 1) {
            logger.error("Homework ID can't be less than 1.");
            logger.debug("findStudentProgressById() - finished with IllegalArgumentException.");
            throw new IllegalArgumentException("Homework ID can't be less than 1.");
        }

        StudentsToHomeWorkEntity entity = null;
        logger.debug("Trying to find Student progress throw homework with student id {} and hw id {}",
                id.getStudentId(), id.getHomeworkId());
        try {
            entity = em.find(StudentsToHomeWorkEntity.class, id);
            logger.debug("Fount entity {}", entity);
        } catch (Exception e) {
            logger.error("Can't find student progress because of error: {} with \ntrace:\n {}", e.getMessage(),
                    e.getStackTrace());
            logger.debug("findStudentProgressById() - finished with DAOException.");
            throw new DAOException("Can't find student progress. Error message: " + e.getMessage());
        }

        logger.debug("Return result: {}", entity);

        logger.debug("findStudentProgressById() - finished.");
        return entity;
    }
}
